package addShowRefs;

import lib.common.ExtensionFileFilter;
import lib.common.Util;
import lib.database.References;

/**
 * @author Ignasi Puigdomenech
 */
public class AddShowRefs extends javax.swing.JFrame {
  private final String pathApp;
  private static final String progName = "AddRefs";
  private final javax.swing.JFileChooser fc;
  private final javax.swing.filechooser.FileFilter filterAll;
  private final javax.swing.filechooser.FileFilter filterRef;
  private References r = null;

  private java.awt.Dimension windowSize = new java.awt.Dimension(400,280);

  /** New-line character(s) to substitute "\n" */
  private static final String nl = System.getProperty("line.separator");


  /** Creates new form AddShowRefs  */
  public AddShowRefs() {
    initComponents();
    pathApp = Main.getPathApp();
    // Define open/save file filters
    fc = new javax.swing.JFileChooser(".");
    filterAll =new ExtensionFileFilter("All files (*.*)", new String[] { "*" });
    filterRef =new ExtensionFileFilter("*.txt", new String[] { "TXT"});
    fc.addChoosableFileFilter(filterRef);
    fc.setFileFilter(filterAll);
    fc.setAcceptAllFileFilterUsed(false);
    //---- Position the window on the screen
    java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
    java.awt.Point frameLocation = new java.awt.Point(-1000,-1000);
    frameLocation.x = Math.max(0, (screenSize.width  - this.getWidth() ) / 2);
    frameLocation.y = Math.max(0, (screenSize.height - this.getHeight() ) / 2);
    this.setLocation(frameLocation);
    //---- Icon
    String iconName = "images/Refs.gif";
    java.net.URL imgURL = this.getClass().getResource(iconName);
    if (imgURL != null) {this.setIconImage(new javax.swing.ImageIcon(imgURL).getImage());}
    else {String errmsg = "Error: Could not load image = \""+iconName+"\"";
        System.out.println(errmsg);
        Main.ErrMsgBx mb = new Main.ErrMsgBx(errmsg, progName);
    }
    this.setTitle("Show references");
  }
  private void start() {
    String t = getFileName(this);
    if(t == null) {
        this.dispose();
        return;
    } else {jLabelFileName.setText(t);}
    r = new References();
    if(!r.readRefsFile(t, false)) {
        String msg = "File:"+nl+"   "+t+nl+"does not exist."+nl+nl+
                         "Create?"+nl+" ";
        Object[] opt = {"Yes", "Exit"};
        int m = javax.swing.JOptionPane.showOptionDialog(this, msg,
                "Save/Show References", javax.swing.JOptionPane.YES_NO_OPTION,
                javax.swing.JOptionPane.WARNING_MESSAGE, null, opt, opt[1]);
        if(m != javax.swing.JOptionPane.YES_OPTION) {
            this.dispose();
            return;
        }
        r.saveRefsFile(this, true);
    }
    fillComboBox();
    windowSize = this.getSize();
  }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel0 = new javax.swing.JLabel();
        jLabelFileName = new javax.swing.JLabel();
        jButtonAdd = new javax.swing.JButton();
        jButtonQuit = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jComboBoxKeys = new javax.swing.JComboBox();
        jButtonShow = new javax.swing.JButton();
        jButtonEdit = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });
        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                formComponentResized(evt);
            }
        });

        jLabel0.setText("Reference file:");

        jLabelFileName.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        jLabelFileName.setText("jLabel4");

        jButtonAdd.setMnemonic('a');
        jButtonAdd.setText("Add new reference");
        jButtonAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAddActionPerformed(evt);
            }
        });

        jButtonQuit.setMnemonic('x');
        jButtonQuit.setText("Exit");
        jButtonQuit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonQuitActionPerformed(evt);
            }
        });

        jLabel1.setText("Keys:");

        jComboBoxKeys.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        jButtonShow.setMnemonic('s');
        jButtonShow.setText("Show");
        jButtonShow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonShowActionPerformed(evt);
            }
        });

        jButtonEdit.setMnemonic('e');
        jButtonEdit.setText("Edit");
        jButtonEdit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonEditActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jButtonShow)
                        .addGap(18, 18, 18)
                        .addComponent(jButtonEdit))
                    .addComponent(jComboBoxKeys, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(0, 10, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jComboBoxKeys, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonShow)
                    .addComponent(jButtonEdit)))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jLabel0, javax.swing.GroupLayout.DEFAULT_SIZE, 313, Short.MAX_VALUE)
                        .addGap(33, 33, 33))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jButtonQuit)
                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(jLabelFileName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jButtonAdd))
                        .addGap(0, 0, Short.MAX_VALUE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel0)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabelFileName)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jButtonAdd)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jButtonQuit)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
      if(windowSize != null) {
        int w = Math.round((float)windowSize.getWidth());
        int h = Math.round((float)windowSize.getHeight());
        if(this.getHeight()<h){this.setSize(this.getWidth(), h);}
        if(this.getWidth()<w){this.setSize(w,this.getHeight());}
      }
    }//GEN-LAST:event_formComponentResized

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        this.dispose();
    }//GEN-LAST:event_formWindowClosing

    private void jButtonQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonQuitActionPerformed
        this.dispose();
    }//GEN-LAST:event_jButtonQuitActionPerformed

    private void jButtonAddActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAddActionPerformed
      this.setVisible(false);
      Thread t = new Thread() {@Override public void run(){
        EditAddRefs sr = new EditAddRefs(r);
        sr.setVisible(true);
        sr.start();
        final String k = sr.waitFor();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {@Override
        public void run() {
            AddShowRefs.this.setVisible(true);
            fillComboBox();
            setComboBoxKey(k);
        }}); //invokeLater(Runnable)
      }};//new Thread
      t.start();
    }//GEN-LAST:event_jButtonAddActionPerformed

    private void jButtonShowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonShowActionPerformed
        if(jComboBoxKeys.getSelectedIndex()<0) {
            javax.swing.JOptionPane.showMessageDialog(this, "No key is selected?", "Show refs", javax.swing.JOptionPane.QUESTION_MESSAGE);
            return;
        }
        java.util.ArrayList<String> a = new java.util.ArrayList<String>();
        a.add(jComboBoxKeys.getSelectedItem().toString());
        r.displayRefs(this, true, null, a);
    }//GEN-LAST:event_jButtonShowActionPerformed

    private void jButtonEditActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonEditActionPerformed
      if(jComboBoxKeys.getSelectedIndex()<0) {
            javax.swing.JOptionPane.showMessageDialog(this, "No key is selected?", "Show refs", javax.swing.JOptionPane.QUESTION_MESSAGE);
            return;
      }
      this.setVisible(false);
      Thread t = new Thread() {@Override public void run(){
        EditAddRefs sr = new EditAddRefs(r);
        sr.setVisible(true);
        String key = jComboBoxKeys.getSelectedItem().toString();
        String reftxt = r.isRefThere(key);
        sr.start(key,reftxt);
        final String k = sr.waitFor();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {@Override
        public void run() {
            AddShowRefs.this.setVisible(true);
            fillComboBox();
            setComboBoxKey(k);
        }}); //invokeLater(Runnable)
      }};//new Thread
      t.start();
    }//GEN-LAST:event_jButtonEditActionPerformed

  private void fillComboBox() {
    Object[] k = r.referenceKeys();
    if(k == null || k.length <=0) {
        jComboBoxKeys.removeAllItems();
        jComboBoxKeys.setEnabled(false);
        jButtonShow.setEnabled(false);
        jButtonEdit.setEnabled(false);
        return;
    }
    jComboBoxKeys.setEnabled(true);
    jButtonShow.setEnabled(true);
    jButtonEdit.setEnabled(true);
    javax.swing.DefaultComboBoxModel dcbm = new javax.swing.DefaultComboBoxModel();
    java.util.ArrayList<String> keyList2 = new java.util.ArrayList<String>();
    for(Object o : k) {keyList2.add(o.toString());}
    java.util.Collections.sort(keyList2);
    k = keyList2.toArray();
    for(Object ex : k) {
        if(ex.toString().length() >0) {dcbm.addElement(ex);}
    }
    jComboBoxKeys.setModel(dcbm);
  }
  private void setComboBoxKey(String key) {
      // -- makes the "key" the selected item in the combo box
      if(key == null || key.trim().length() <=0 || jComboBoxKeys.getItemCount() <=0) {return;}
      int fnd = -1;
      for(int j=0; j < jComboBoxKeys.getItemCount(); j++) {
          if(jComboBoxKeys.getItemAt(j).toString().equalsIgnoreCase(key)) {fnd = j; break;}
      }
      if(fnd >-1) {jComboBoxKeys.setSelectedIndex(fnd);}
  }

  //<editor-fold defaultstate="collapsed" desc="getFileName()">
  /**  Get a file name from the user using an Open File dialog.
   * If the file exists and it is not empty, read it and save it to sort the entries.
   * @param frame the parent component of the dialog
   * @return "null" if the user cancels the opertion; a file name otherwise. */
  private String getFileName(java.awt.Component frame) {
      // Ask the user for a file name using a Open File dialog
      frame.setCursor(new java.awt.Cursor(java.awt.Cursor.WAIT_CURSOR));
      fc.setFileFilter(filterAll);
      fc.addChoosableFileFilter(filterRef);
      fc.setAcceptAllFileFilterUsed(false);
      fc.setDialogTitle("Select a reference file:");
      fc.setFileSelectionMode(javax.swing.JFileChooser.FILES_ONLY);
      java.io.File defFile = new java.io.File("References.txt");
      fc.setSelectedFile(defFile);
      java.io.File currDir = new java.io.File(pathApp);
      fc.setCurrentDirectory(currDir);
      // show the Open File dialog using the System look and feel
      javax.swing.LookAndFeel defLaF = javax.swing.UIManager.getLookAndFeel();
      try {javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());}
      catch (ClassNotFoundException ex) {}
      catch (InstantiationException ex) {}
      catch (IllegalAccessException ex) {}
      catch (javax.swing.UnsupportedLookAndFeelException ex) {}
      fc.updateUI();
      frame.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
      int returnVal;
      returnVal = fc.showOpenDialog(frame);
      // reset the look and feel
      try {javax.swing.UIManager.setLookAndFeel(defLaF);} catch (javax.swing.UnsupportedLookAndFeelException ex) {}
      Util.configureOptionPane();

      if(returnVal == javax.swing.JFileChooser.APPROVE_OPTION) {
          int answer;
          java.io.File refFile = fc.getSelectedFile();
          String refFileName;
          if(!refFile.getName().toLowerCase().endsWith(".txt")) {
              refFileName = refFile.getAbsolutePath()+".txt";
              if(refFile.getName().contains(".")) {
                  String name = refFile.getName()+".txt";
                  Object[] opt = {"OK", "Cancel"};
                  answer = javax.swing.JOptionPane.showOptionDialog(frame,
                        "Note: file name must end with \".txt\""+nl+nl+
                        "The file name is:"+nl+"\""+name+"\"",
                        progName, javax.swing.JOptionPane.YES_NO_OPTION,
                        javax.swing.JOptionPane.WARNING_MESSAGE, null, opt, opt[1]);
                        if(answer != javax.swing.JOptionPane.YES_OPTION) {return null;}
              }
              refFile = new java.io.File(refFileName);
          }
          if(refFile.exists()) {
              Object[] opt = {"Ok","Cancel"};
              answer = javax.swing.JOptionPane.showOptionDialog(frame,
                        "File \""+refFile.getName()+"\" already exists!"+nl+nl+
                        "If you add or delete references"+nl+"the file will be overwritten",
                        progName, javax.swing.JOptionPane.YES_NO_OPTION,
                        javax.swing.JOptionPane.QUESTION_MESSAGE,null,opt,opt[0]);
              if(answer != javax.swing.JOptionPane.YES_OPTION) {return null;}
          }
          if(refFile.exists() && !refFile.canWrite()) {
              javax.swing.JOptionPane.showMessageDialog(frame,
                        "Can not overwrite file \""+refFile.getName()+"\"."+nl+
                        "The file or the directory is perhpas write-protected.",
                        progName, javax.swing.JOptionPane.ERROR_MESSAGE);
              return null;
          }
          return refFile.getAbsolutePath();
      } // if returnVal = JFileChooser.APPROVE_OPTION
      return null;
  } // getFileName()
  // </editor-fold>

    /** @param args the command line arguments  */
    public static void main(String args[]) {
        //---- for JOptionPanes set the default button to the one with the focus
        //     so that pressing "enter" behaves as expected:
        javax.swing.UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
        //     and make the arrow keys work:
        Util.configureOptionPane();

        /*  Create and display the form  */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                AddShowRefs sr = new AddShowRefs();
                sr.setVisible(true);
                sr.start();
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonAdd;
    private javax.swing.JButton jButtonEdit;
    private javax.swing.JButton jButtonQuit;
    private javax.swing.JButton jButtonShow;
    private javax.swing.JComboBox jComboBoxKeys;
    private javax.swing.JLabel jLabel0;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabelFileName;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration//GEN-END:variables
}
